package com.fysports.web.config.asyn;

import com.jfinal.log.Log;
import com.fysports.web.model.system.SystemLog;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;


/**
 * 独立线程记录日志
 * Created by konbluesky
 * Date : 14-9-11 下午4:16
 * Project : JdmData_WebServer
 */
public class ThreadSystemLog extends Thread {
    private static Log log = Log.getLog(ThreadSystemLog.class);

    private static final int queueSize = 5000; // 入库队列大小

    private static boolean threadRun = true; // 线程是否运行

    /**
     * 队列
     */
    //private static final BlockingQueue<Syslog> queue = new LinkedBlockingQueue<Syslog>(queueSize);

    private static Queue<SystemLog> queue = new ConcurrentLinkedQueue<SystemLog>();
            //	此队列按照 FIFO（先进先出）原则对元素进行排序


    /**
     * 向队列中增加Syslog对象，基于LinkedBlockingQueue
     *
     * @param SystemLog public static void add(Syslog sysLog){
     *                  try {
     *                  log.debug("put操作日志到缓存queue start......");
     *                  queue.put(sysLog);
     *                  log.debug("put操作日志到缓存queue end......");
     *                  } catch (InterruptedException e) {
     *                  log.error("put操作日志到缓存queue异常");
     *                  throw new RuntimeException("ThreadSysLog -> add Exception");
     *                  }
     *                  }
     */

    public static void setThreadRun(boolean threadRun) {
        ThreadSystemLog.threadRun = threadRun;
    }


    /**
     * 向队列中增加Syslog对象，基于ConcurrentLinkedQueue
     *
     * @param syslog
     */
    public static void add(SystemLog syslog) {
        if (null != syslog) {    // 此队列不允许使用 null 元素

            synchronized (queue) {
                if (queue.size() <= queueSize) {
                    queue.offer(syslog);
                }
                else {
                    queue.poll(); // 获取并移除此队列的头，如果此队列为空，则返回 null

                    queue.offer(syslog); // 将指定元素插入此队列的尾部

                    log.error("日志队列：超过" + queueSize);
                }
            }
        }
    }


    /**
     * 获取Syslog对象，基于ConcurrentLinkedQueue
     *
     * @return
     */
    public static SystemLog getSyslog() {
        synchronized (queue) {
            if (queue.isEmpty()) {
                return null;
            }
            else {
                return queue.poll(); // 获取并移除此队列的头，如果此队列为空，则返回 null

            }
        }
    }


    /**
     * 启动入库线程
     */
    public static void startSaveDBThread() {
        try {
            for (int i = 0; i < 10; i++) {
                Thread insertDbThread = new Thread(new Runnable() {
                    public void run() {
                        while (threadRun) {
                            try {
                                // 取队列数据

                                //Syslog sysLog = queue.take(); // 基于LinkedBlockingQueue

                                SystemLog sysLog = getSyslog();
                                if (null == sysLog) {
                                    Thread.sleep(200);
                                }
                                else {
                                    log.debug("保存操作日志到数据库start......");
                                    sysLog.save();// 日志入库

                                    log.debug("保存操作日志到数据库end......");
                                }
                            }
                            catch (Exception e) {
                                log.error("保存操作日志到数据库异常",e);
                                throw new RuntimeException("ThreadSysLog -> save Exception");
                            }
                        }
                    }
                });

                insertDbThread.setName("Thread-SysLog-insertDB-" + (i + 1));
                insertDbThread.start();
            }
        }
        catch (Exception e) {
            throw new RuntimeException("ThreadSysLog new Thread Exception");
        }
    }
}
